"""
Redis utility module for managing Redis keys and cache operations.
This module implements the Redis key design pattern specified in the requirements.
"""

from app import redis_client
import json

class RedisKeys:
    """Constants for Redis key patterns"""
    USER_KEY = "user:{user_id}"
    USER_FORMS_KEY = "user_forms:{user_id}"
    FORM_KEY = "form:{form_id}"
    FORM_SUBMISSIONS_COUNT_KEY = "form_submissions_count:{form_id}"
    FORM_ANSWERS_KEY = "form_answers:{form_id}"
    SUBMISSION_KEY = "submission:{submission_id}"
    USER_RECENT_SUBMISSIONS_KEY = "user_recent_submissions:{user_id}"

class RedisManager:
    """Manager class for Redis operations"""
    
    @staticmethod
    def get_user_key(user_id):
        """Generate Redis key for user information"""
        return RedisKeys.USER_KEY.format(user_id=user_id)
    
    @staticmethod
    def get_user_forms_key(user_id):
        """Generate Redis key for user forms list"""
        return RedisKeys.USER_FORMS_KEY.format(user_id=user_id)
    
    @staticmethod
    def get_form_key(form_id):
        """Generate Redis key for form details"""
        return RedisKeys.FORM_KEY.format(form_id=form_id)
    
    @staticmethod
    def get_form_submissions_count_key(form_id):
        """Generate Redis key for form submissions count"""
        return RedisKeys.FORM_SUBMISSIONS_COUNT_KEY.format(form_id=form_id)
    
    @staticmethod
    def get_form_answers_key(form_id):
        """Generate Redis key for form answers"""
        return RedisKeys.FORM_ANSWERS_KEY.format(form_id=form_id)
    
    @staticmethod
    def get_submission_key(submission_id):
        """Generate Redis key for submission details"""
        return RedisKeys.SUBMISSION_KEY.format(submission_id=submission_id)
    
    @staticmethod
    def get_user_recent_submissions_key(user_id):
        """Generate Redis key for user recent submissions"""
        return RedisKeys.USER_RECENT_SUBMISSIONS_KEY.format(user_id=user_id)
    
    @staticmethod
    def cache_user(user_id, user_data, expire_time=3600):
        """Cache user information in Redis"""
        key = RedisManager.get_user_key(user_id)
        redis_client.setex(key, expire_time, json.dumps(user_data))
    
    @staticmethod
    def get_cached_user(user_id):
        """Retrieve cached user information from Redis"""
        key = RedisManager.get_user_key(user_id)
        data = redis_client.get(key)
        return json.loads(data) if data else None
    
    @staticmethod
    def cache_form(form_id, form_data, expire_time=3600):
        """Cache form details in Redis"""
        key = RedisManager.get_form_key(form_id)
        redis_client.setex(key, expire_time, json.dumps(form_data))
    
    @staticmethod
    def get_cached_form(form_id):
        """Retrieve cached form details from Redis"""
        key = RedisManager.get_form_key(form_id)
        data = redis_client.get(key)
        return json.loads(data) if data else None
    
    @staticmethod
    def cache_submission(submission_id, submission_data, expire_time=3600):
        """Cache submission details in Redis"""
        key = RedisManager.get_submission_key(submission_id)
        redis_client.setex(key, expire_time, json.dumps(submission_data))
    
    @staticmethod
    def get_cached_submission(submission_id):
        """Retrieve cached submission details from Redis"""
        key = RedisManager.get_submission_key(submission_id)
        data = redis_client.get(key)
        return json.loads(data) if data else None
    
    @staticmethod
    def cache_user_forms(user_id, forms_list, expire_time=1800):
        """Cache user forms list in Redis"""
        key = RedisManager.get_user_forms_key(user_id)
        redis_client.setex(key, expire_time, json.dumps(forms_list))
    
    @staticmethod
    def get_cached_user_forms(user_id):
        """Retrieve cached user forms list from Redis"""
        key = RedisManager.get_user_forms_key(user_id)
        data = redis_client.get(key)
        return json.loads(data) if data else None
    
    @staticmethod
    def increment_form_submissions_count(form_id):
        """Increment form submissions count in Redis"""
        key = RedisManager.get_form_submissions_count_key(form_id)
        return redis_client.incr(key)
    
    @staticmethod
    def get_form_submissions_count(form_id):
        """Get form submissions count from Redis"""
        key = RedisManager.get_form_submissions_count_key(form_id)
        count = redis_client.get(key)
        return int(count) if count else 0
    
    @staticmethod
    def add_user_recent_submission(user_id, submission_data, max_length=10):
        """Add a submission to user's recent submissions list"""
        key = RedisManager.get_user_recent_submissions_key(user_id)
        redis_client.lpush(key, json.dumps(submission_data))
        redis_client.ltrim(key, 0, max_length - 1)
    
    @staticmethod
    def get_user_recent_submissions(user_id, count=10):
        """Get user's recent submissions from Redis"""
        key = RedisManager.get_user_recent_submissions_key(user_id)
        submissions = redis_client.lrange(key, 0, count - 1)
        return [json.loads(sub) for sub in submissions] if submissions else []
    
    @staticmethod
    def delete_user_cache(user_id):
        """Delete user-related cache from Redis"""
        keys_to_delete = [
            RedisManager.get_user_key(user_id),
            RedisManager.get_user_forms_key(user_id),
            RedisManager.get_user_recent_submissions_key(user_id)
        ]
        redis_client.delete(*keys_to_delete)
    
    @staticmethod
    def delete_form_cache(form_id):
        """Delete form-related cache from Redis"""
        keys_to_delete = [
            RedisManager.get_form_key(form_id),
            RedisManager.get_form_submissions_count_key(form_id),
            RedisManager.get_form_answers_key(form_id)
        ]
        redis_client.delete(*keys_to_delete)
    
    @staticmethod
    def delete_submission_cache(submission_id):
        """Delete submission-related cache from Redis"""
        key = RedisManager.get_submission_key(submission_id)
        redis_client.delete(key)